Skip to content

Validate Guest Address Ranges for Overlapping Regions in map_region#1464

Open
Richard-Durkee wants to merge 1 commit into
hyperlight-dev:mainfrom
Richard-Durkee:fix/validate-map-region-overlap
Open

Validate Guest Address Ranges for Overlapping Regions in map_region#1464
Richard-Durkee wants to merge 1 commit into
hyperlight-dev:mainfrom
Richard-Durkee:fix/validate-map-region-overlap

Conversation

@Richard-Durkee
Copy link
Copy Markdown

@Richard-Durkee Richard-Durkee commented May 19, 2026

Add overlap validation to HyperlightVm::map_region to enforce the safety contract documented on VirtualMachine::map_memory, which requires non-overlapping regions.

Checks the new region against existing dynamically mapped regions (mmap_regions), the snapshot region (starting at BASE_ADDRESS), and the scratch region (at the top of the guest physical address space).

Adds Overlapping variant to MapRegionError with a descriptive message showing both the new and conflicting ranges.

Also adds early validation at the MultiUseSandbox::map_region level to reject invalid input before side effects (snapshot reset) occur.

Tested on KVM (c8i.2xlarge with nested virtualization enabled).

Closes #1289

@Richard-Durkee Richard-Durkee changed the title fix: validate guest address ranges for overlapping regions in map_region Validate Guest Address Ranges for Overlapping Regions in map_region May 19, 2026
@ludfjig ludfjig added the kind/bugfix For PRs that fix bugs label May 19, 2026
@Richard-Durkee Richard-Durkee force-pushed the fix/validate-map-region-overlap branch from 644165f to bb16213 Compare May 19, 2026 18:43
Copy link
Copy Markdown
Contributor

@ludfjig ludfjig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for your contribution!

I think we can drop the validation in MultiUseSandbox::map_region entirely and rely on the check inside HyperlightVm::map_region, then reorder so the call happens before the snapshot reset:

unsafe { self.vm.map_region(rgn) }.map_err(HyperlightVmError::MapRegion)?;
self.snapshot = None;
self.mem_mgr.mapped_rgns += 1;

The same pattern can probably applies to map_file_cow too I think. What do you think about this?

@Richard-Durkee Richard-Durkee force-pushed the fix/validate-map-region-overlap branch 2 times, most recently from 3075ff3 to f2c4072 Compare May 19, 2026 21:38
@Richard-Durkee
Copy link
Copy Markdown
Author

thanks for your contribution!

I think we can drop the validation in MultiUseSandbox::map_region entirely and rely on the check inside HyperlightVm::map_region, then reorder so the call happens before the snapshot reset:

unsafe { self.vm.map_region(rgn) }.map_err(HyperlightVmError::MapRegion)?;
self.snapshot = None;
self.mem_mgr.mapped_rgns += 1;

The same pattern can probably applies to map_file_cow too I think. What do you think about this?

Thanks for the feedback!

This makes sense to me. I just pushed again and included these suggestions. Please let me know if there are any other changes you'd like.

@ludfjig
Copy link
Copy Markdown
Contributor

ludfjig commented May 20, 2026

thanks for your contribution!
I think we can drop the validation in MultiUseSandbox::map_region entirely and rely on the check inside HyperlightVm::map_region, then reorder so the call happens before the snapshot reset:

unsafe { self.vm.map_region(rgn) }.map_err(HyperlightVmError::MapRegion)?;
self.snapshot = None;
self.mem_mgr.mapped_rgns += 1;

The same pattern can probably applies to map_file_cow too I think. What do you think about this?

Thanks for the feedback!

This makes sense to me. I just pushed again and included these suggestions. Please let me know if there are any other changes you'd like.

Looks great! Just one minor thing I just realized the page-table "tail" of compacted snapshots are not mapped into the vm, so the could be less than mem_size(). I think switching to

#[cfg(not(unshared_snapshot_mem))]
let snap_end = snap_start + snapshot.guest_mapped_size();
#[cfg(unshared_snapshot_mem)]
let snap_end = snap_start + snapshot.mem_size();

should do it. Thanks!

@Richard-Durkee Richard-Durkee force-pushed the fix/validate-map-region-overlap branch 2 times, most recently from cfd33a6 to fa24c67 Compare May 20, 2026 23:01
@Richard-Durkee
Copy link
Copy Markdown
Author

Ah, okay -- I just learned about compacted snapshots. Pushed the change. Thanks again for the help.

ludfjig
ludfjig previously approved these changes May 21, 2026
Copy link
Copy Markdown
Contributor

@ludfjig ludfjig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Would you mind gpg-sign your commit. Thanks alot!

@Richard-Durkee Richard-Durkee force-pushed the fix/validate-map-region-overlap branch from fa24c67 to 5f016ed Compare May 21, 2026 03:41
Copy link
Copy Markdown
Contributor

@danbugs danbugs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly nits, nothing blocking. LGTM.

Comment thread src/hyperlight_host/src/hypervisor/hyperlight_vm/mod.rs Outdated
Comment thread src/hyperlight_host/src/hypervisor/hyperlight_vm/mod.rs
Comment thread src/hyperlight_host/src/sandbox/initialized_multi_use.rs
Copilot AI review requested due to automatic review settings May 22, 2026 20:48
@Richard-Durkee Richard-Durkee force-pushed the fix/validate-map-region-overlap branch from 5f016ed to 5e09e95 Compare May 22, 2026 20:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR centralizes guest-memory overlap detection inside HyperlightVm::map_region and adjusts sandbox snapshot invalidation to occur only after successful mappings, adding tests to validate overlap behavior.

Changes:

  • Add overlap detection (dynamic regions + snapshot + scratch) to HyperlightVm::map_region via a new MapRegionError::Overlapping variant.
  • Move MultiUseSandbox snapshot reset to occur after map_region succeeds.
  • Add unit tests covering overlapping, partially overlapping, adjacent, and reserved-region overlap scenarios.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/hyperlight_host/src/sandbox/initialized_multi_use.rs Reorders snapshot reset after successful mapping; removes redundant overlap scanning; adds overlap-focused tests.
src/hyperlight_host/src/hypervisor/hyperlight_vm/mod.rs Implements centralized overlap checks and surfaces them through a dedicated Overlapping mapping error.
Comments suppressed due to low confidence (1)

src/hyperlight_host/src/hypervisor/hyperlight_vm/mod.rs:1

  • Adding a new variant to a pub enum is a semver-breaking change for downstream crates that exhaustively match on MapRegionError. If this type is part of the public API surface, consider marking the enum #[non_exhaustive] (and updating callers accordingly), or otherwise gating this behind a non-public error type / major version bump.
/*

Comment on lines +447 to +475
let snap_start = crate::mem::layout::SandboxMemoryLayout::BASE_ADDRESS;
#[cfg(not(unshared_snapshot_mem))]
let snap_end = snap_start + snapshot.guest_mapped_size();
#[cfg(unshared_snapshot_mem)]
let snap_end = snap_start + snapshot.mem_size();
if new_start < snap_end && new_end > snap_start {
return Err(MapRegionError::Overlapping {
new_start,
new_end,
existing_start: snap_start,
existing_end: snap_end,
});
}
}

// Check against the scratch region
if let Some(ref scratch) = self.scratch_memory {
let scratch_start =
hyperlight_common::layout::scratch_base_gpa(scratch.mem_size()) as usize;
let scratch_end = scratch_start + scratch.mem_size();
if new_start < scratch_end && new_end > scratch_start {
return Err(MapRegionError::Overlapping {
new_start,
new_end,
existing_start: scratch_start,
existing_end: scratch_end,
});
}
}
Comment on lines +2598 to +2602
let err = unsafe { sbox.map_region(&region2) }.unwrap_err();
assert!(
format!("{err:?}").contains("Overlapping"),
"Expected Overlapping error, got: {err:?}"
);
Comment on lines +2580 to +2586
#[test]
fn map_region_rejects_overlapping_regions() {
let mut sbox: MultiUseSandbox = {
let path = simple_guest_as_string().unwrap();
let u_sbox = UninitializedSandbox::new(GuestBinary::FilePath(path), None).unwrap();
u_sbox.evolve().unwrap()
};
Closes hyperlight-dev#1289

Signed-off-by: Richard Durkee <Richard-Durkee@users.noreply.github.com>
@Richard-Durkee Richard-Durkee force-pushed the fix/validate-map-region-overlap branch from 5e09e95 to 7b5b668 Compare May 22, 2026 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bugfix For PRs that fix bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate guest address ranges for overlapping regions in map_region / map_file_cow

4 participants